import org.slf4j.Logger
import org.slf4j.LoggerFactory
import kotlin.reflect.KClass
import kotlin.reflect.full.createInstance
import kotlin.reflect.full.isSubclassOf

/**
 * 默认的插件管理器类，继承自PluginsManager。
 * 负责加载和管理插件，以及分离出需要在分析前后执行的插件。
 */
class DefaultPluginsManager : PluginsManager {
    protected val log:Logger = LoggerFactory.getLogger(this::class.java)
    // 存储所有插件的列表
    private val pluginsList = mutableListOf<Plugins>()
    // 存储需要在分析前执行的插件列表
    private val beforeAnalyzableList= mutableListOf<BeforeAnalyzable>()
    // 存储需要在分析后执行的插件列表
    private val afterAnalyzableList= mutableListOf<AfterAnalyzable>()
    // 配置对象，用于获取插件的相关配置
    private val config = Config

    // 初始化时加载所有插件
    init {
        this.pluginsList.addAll(findPlugins())
    }

    /**
     * 查找并加载所有插件。
     *
     * @return 插件列表
     */
    override fun findPlugins(): List<Plugins> {
        val pluginList = mutableListOf<Plugins>()
        for (pluginName in config.getPlugins()) {
            // 获取path路径下所有kotlin文件的实例对象
            try {
                // 获取类的Class对象
                val clazz: KClass<*> = Class.forName(pluginName).kotlin
                // 创建实例
                if (clazz.isSubclassOf(Plugins::class)) {
                    val instance = clazz.createInstance() as Plugins
                    log.info("已加载插件：${instance.getPluginName()}")
                    pluginList.add(instance)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return pluginList.toList()
    }

    /**
     * 获取所有需要在分析后执行的插件。
     *
     * @return 分析后执行的插件列表
     */
    override fun getAfterAnalyzablePlugins(): List<AfterAnalyzable> {
        for (plugin in pluginsList) {
            if (plugin is AfterAnalyzable && !afterAnalyzableList.contains(plugin)) {
                afterAnalyzableList.add(plugin)
            }
        }
        afterAnalyzableList.sortedBy { it.getOrder() }
        return afterAnalyzableList.toList()
    }

    /**
     * 获取所有需要在分析前执行的插件。
     *
     * @return 分析前执行的插件列表
     */
    override fun getBeforeAnalyzablePlugins(): List<BeforeAnalyzable> {
        for (plugin in pluginsList) {
            if (plugin is BeforeAnalyzable && !beforeAnalyzableList.contains(plugin)) {
                beforeAnalyzableList.add(plugin)
            }
        }
        beforeAnalyzableList.sortedBy { it.getOrder() }
        return beforeAnalyzableList.toList()
    }
}
